package com.farm.kaiping.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.farm.common.config.OssConfig;
import com.farm.common.security.SecurityUtils;
import com.farm.common.util.OssUtil;
import com.farm.kaiping.entity.SysFile;
import com.farm.kaiping.po.SysFilePO;
import com.farm.kaiping.mapper.SysFileMapper;
import com.farm.kaiping.service.SysFileService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.farm.common.util.StringRange;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 文件管理表(SysFile)表服务实现类
 *
 * @author zhuhui
 * @since 2024-11-26 22:58:20
 */
@Service
@Slf4j
@AllArgsConstructor
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements SysFileService {

	@Autowired
	private final OssConfig ossConfig;
	@Autowired
	private final OssUtil ossUtil;
    
	private LambdaQueryWrapper<SysFile> generateQueryWrapper(SysFilePO sysFilePO){
		LambdaQueryWrapper<SysFile> queryWrapper = new LambdaQueryWrapper<>();
		// 编号
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysFilePO.getId()), SysFile::getId, sysFilePO.getId());
		queryWrapper.in(ObjectUtil.isNotEmpty(sysFilePO.getIdList()), SysFile::getId, sysFilePO.getIdList());
		// 文件名称
		queryWrapper.like(ObjectUtil.isNotEmpty(sysFilePO.getFileName()), SysFile::getFileName, sysFilePO.getFileName());
		// 桶名称
		queryWrapper.like(ObjectUtil.isNotEmpty(sysFilePO.getBucketName()), SysFile::getBucketName, sysFilePO.getBucketName());
		// 文件原名称
		queryWrapper.like(ObjectUtil.isNotEmpty(sysFilePO.getOriginal()), SysFile::getOriginal, sysFilePO.getOriginal());
		// 文件类型
		queryWrapper.like(ObjectUtil.isNotEmpty(sysFilePO.getType()), SysFile::getType, sysFilePO.getType());
		// 文件大小
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysFilePO.getFileSize()), SysFile::getFileSize, sysFilePO.getFileSize());
		// 是否删除(0否1是)
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysFilePO.getDelFlag()), SysFile::getDelFlag, sysFilePO.getDelFlag());
        queryWrapper.eq(ObjectUtil.isEmpty(sysFilePO.getDelFlag()), SysFile::getDelFlag, 0);
		// 新增时间
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysFilePO.getCreateTime()), SysFile::getCreateTime, sysFilePO.getCreateTime());
		// 创建人ID
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysFilePO.getCreateUserId()), SysFile::getCreateUserId, sysFilePO.getCreateUserId());
		// 创建人姓名
		queryWrapper.like(ObjectUtil.isNotEmpty(sysFilePO.getCreateUserName()), SysFile::getCreateUserName, sysFilePO.getCreateUserName());
		// 更新时间
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysFilePO.getUpdateTime()), SysFile::getUpdateTime, sysFilePO.getUpdateTime());
		// 更新人ID
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysFilePO.getUpdateUserId()), SysFile::getUpdateUserId, sysFilePO.getUpdateUserId());
		// 更新人姓名
		queryWrapper.like(ObjectUtil.isNotEmpty(sysFilePO.getUpdateUserName()), SysFile::getUpdateUserName, sysFilePO.getUpdateUserName());
		// 租户ID
		queryWrapper.eq(ObjectUtil.isNotEmpty(sysFilePO.getTenantId()), SysFile::getTenantId, sysFilePO.getTenantId());
		// 创建时间时间区间查询
		queryWrapper.ge(ObjectUtil.isNotEmpty(StringRange.getOne(sysFilePO.getCreateTimeBetween(),0)), SysFile::getCreateTime,StringRange.getOne(sysFilePO.getCreateTimeBetween(),0));
		queryWrapper.le(ObjectUtil.isNotEmpty(StringRange.getOne(sysFilePO.getCreateTimeBetween(),1)), SysFile::getCreateTime,StringRange.getOne(sysFilePO.getCreateTimeBetween(),1));
		// 更新时间时间区间查询
		queryWrapper.ge(ObjectUtil.isNotEmpty(StringRange.getOne(sysFilePO.getUpdateTimeBetween(),0)), SysFile::getUpdateTime,StringRange.getOne(sysFilePO.getUpdateTimeBetween(),0));
		queryWrapper.le(ObjectUtil.isNotEmpty(StringRange.getOne(sysFilePO.getUpdateTimeBetween(),1)), SysFile::getUpdateTime,StringRange.getOne(sysFilePO.getUpdateTimeBetween(),1));

		queryWrapper.orderByDesc(SysFile::getCreateTime,SysFile::getId);
		return queryWrapper;
	}

	 /**
	  * @describe 分页查询文件管理表
	  * @author zhuhui
	  * @date 2024-11-26 22:58:20
	  */
	@Override
	public Page<SysFile> getSysFilePage(Page page, SysFilePO sysFilePO){
		LambdaQueryWrapper<SysFile> queryWrapper = this.generateQueryWrapper(sysFilePO);
        return this.baseMapper.selectPage(page, queryWrapper);
	}
	
	/**
     * @describe 查询文件管理表list
     * @author  zhuhui
     * @date  2024-11-26 22:58:20
     */
	@Override
	public List<SysFile> getSysFileList(SysFilePO sysFilePO){
		LambdaQueryWrapper<SysFile> queryWrapper = this.generateQueryWrapper(sysFilePO);
        return this.baseMapper.selectList(queryWrapper);
	}
	
	/**
     * @describe 获取一条数据 文件管理表
     * @author  zhuhui
     * @date  2024-11-26 22:58:20
     */
	@Override
	public SysFile getSysFile(SysFilePO sysFilePO){
		LambdaQueryWrapper<SysFile> queryWrapper = this.generateQueryWrapper(sysFilePO);
        queryWrapper.last("LIMIT 1");
        return this.baseMapper.selectOne(queryWrapper);
	}

    /**
     * @describe 新增文件管理表
     * @author  zhuhui
     * @date  2024-11-26 22:58:20
     */
	@Override
	public Long saveSysFile(SysFilePO sysFilePO) {
        sysFilePO.setDelFlag(0);
		if (ObjectUtil.isNotEmpty(SecurityUtils.getUser())){
			sysFilePO.setTenantId(SecurityUtils.getUser().getTenantId());// 租户ID
			sysFilePO.setCreateUserId(SecurityUtils.getUser().getUserId());// 创建人
			sysFilePO.setCreateUserName(SecurityUtils.getUser().getRealName());// 创建人
		}else{
			sysFilePO.setTenantId(1);// 租户ID
		}
		sysFilePO.setCreateTime(LocalDateTime.now());
		sysFilePO.setUpdateTime(LocalDateTime.now());
		SysFile sysFile = BeanUtil.copyProperties(sysFilePO, SysFile.class);
		this.save(sysFile);
		return sysFile.getId();
	}

	/**
     * @describe 通过id删除文件管理表
     * @author  zhuhui
     * @date  2024-11-26 22:58:20
     */
	@Override
	public String removeSysFile(SysFilePO sysFilePO) {
		if (ObjectUtil.isEmpty(sysFilePO.getBatchDel())) {
			throw new RuntimeException("删除数据未选择");
		}
		LambdaUpdateWrapper<SysFile> removeWrapper = new LambdaUpdateWrapper<>();
		removeWrapper.in(SysFile::getId, sysFilePO.getBatchDel());
		removeWrapper.set(SysFile::getDelFlag,1);
		removeWrapper.set(SysFile::getUpdateUserId,SecurityUtils.getUser().getUserId());// 更新人
		removeWrapper.set(SysFile::getUpdateUserName,SecurityUtils.getUser().getRealName());// 更新人
		removeWrapper.set(SysFile::getUpdateTime,LocalDateTime.now());

		this.update(removeWrapper);
		return "删除成功";
	}

	private void fileLog(MultipartFile file, String fileName) {
		SysFilePO sysFilePO = new SysFilePO();
		sysFilePO.setFileName(fileName);
		sysFilePO.setOriginal(file.getOriginalFilename());
		sysFilePO.setFileSize(file.getSize());
		sysFilePO.setType(FileUtil.extName(file.getOriginalFilename()));
		sysFilePO.setBucketName(ossConfig.getBucketName());
		this.saveSysFile(sysFilePO);
	}

	@Override
	public Map<String, String> uploadFile(MultipartFile file) {
		if (ObjectUtil.isNotNull(file.getOriginalFilename())){
			if (file.getOriginalFilename().length()>100){
				throw new RuntimeException("原始文件名过长，请限制100位字符以内");
			}
		}

		String objectName = ossUtil.getObjectName(file.getOriginalFilename());
		if (StrUtil.isEmpty(objectName)){
			throw new RuntimeException("文件名不能为空");
		}

		String upload;
		try {
			upload = ossUtil.upload(objectName, file);
			// 文件管理数据记录,收集管理追踪文件
			fileLog(file, objectName);
		}catch (Exception e) {
			log.error("上传失败", e);
			throw new RuntimeException("上传失败:"+e.getMessage());
		}

		Map<String, String> resultMap = new HashMap<>();
		resultMap.put("fileName", objectName);
		resultMap.put("url", upload);
		return resultMap;
	}

	@Override
	public void postDownload(HttpServletResponse response, String objectName) {
		String myContentType = "application/x-download";
		ossUtil.download(response, objectName,myContentType);
	}

	@Override
	public void getDownLoad(HttpServletResponse response, String objectName) {
		String string = Base64.decodeStr(objectName);
		ossUtil.download(response, string,null);
	}


}

